package com.eastdigit.bpm.cmd;

import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.HistoricActivityInstanceQueryImpl;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.cmd.NeedsActiveTaskCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;

import java.util.List;
import java.util.Map;

/**
 * 
 * <p>Project: gjzt-web </p>
 * <p>Description:  用户任务虚拟跳转: 目标为同一execution的历史用户任务环节</p>
 *
 * @author jun
 * @date 2016-5-10
 */
public class TaskJumpActivitiCmd extends NeedsActiveTaskCmd<Void> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String targetActivityId;
	private Map<String, Object> variables;
	protected boolean localScope;

	public TaskJumpActivitiCmd(String taskId, String targetActivityId, Map<String, Object> variables) {
		super(taskId);
		this.targetActivityId = targetActivityId;
		this.variables = variables;
	}
	
	public TaskJumpActivitiCmd(String taskId, String targetActivityId, Map<String, Object> variables, boolean localScope) {
		super(taskId);
		this.targetActivityId = targetActivityId;
		this.variables = variables;
		this.localScope = localScope;
	}

	protected Void execute(CommandContext commandContext, TaskEntity task) {
		
		ExecutionEntity execution = task.getExecution(); 
        ProcessDefinitionImpl processDefinition = execution.getProcessDefinition();
        
        //检查当前环节类型是否userTask, 不包含多实例任务
        ActivityImpl currentActivityImpl = processDefinition.findActivity(task.getTaskDefinitionKey());
        if(!(currentActivityImpl.getActivityBehavior() instanceof UserTaskActivityBehavior)){
        	throw new ActivitiIllegalArgumentException("current ActivityId is not userTaskActivity !");
        }
        
		if(targetActivityId == null) {
		    throw new ActivitiIllegalArgumentException("targetActivityId is null !");
		}else if (targetActivityId.equals(task.getTaskDefinitionKey())){
			throw new ActivitiIllegalArgumentException("targetActivityId is same as current task !");
		}
		
		//检查目标环节是否历史用户任务环节
		List<HistoricActivityInstance> hisActInsts = new HistoricActivityInstanceQueryImpl(commandContext)
				.executionId(task.getExecutionId()).activityId(targetActivityId).activityType("userTask")
				.finished()
				.orderByHistoricActivityInstanceStartTime()
				.desc()//取最后一次历史任务
				.list();
		HistoricActivityInstance targetActivityInst = (hisActInsts != null && !hisActInsts.isEmpty()) ? hisActInsts.get(0) : null;
		if(targetActivityInst == null){
			throw new ActivitiIllegalArgumentException("targetHisActivityInst is null !");
		}
		
		if (variables != null) {
			if (localScope) {
				task.setVariablesLocal(variables);
			} else if (task.getExecutionId() != null) {
				task.setExecutionVariables(variables);
			} else {
				task.setVariables(variables);
			}
		}

		
        ActivityImpl toActivityImpl = processDefinition.findActivity(targetActivityId);
        
        task.fireEvent("complete");
        execution.destroyScope("user operation");
        
        Context
        .getCommandContext()
        .getTaskEntityManager()
        .deleteTask(task, TaskEntity.DELETE_REASON_COMPLETED, false);
        execution.removeTask(task);
        
        Context.getCommandContext().getHistoryManager()
        .recordActivityEnd((ExecutionEntity) execution);
        
        execution.executeActivity(toActivityImpl);
		
        
		return null;
	}

}
